/*
	Работа с журналом
*/
#include "defines.h"


//Массив записей
P32T JournalRecords[MAX_COUNT_PER_PACKET];
//Количество записей
U8 JournalRecordsCount=0;

//Значение тиков начиная с которых, необходимо вернуть записи
U64 findTicks;

/*
	Ищем записи и заносим их в массив, если надо
	Максимум за раз читаем MAX_COUNT_PER_PACKET записи
*/
int journal_get_records()
{
		
	DateTimeT dt;
	P32T record;
	FILE *f;
	char path[100];
	
	//Текущее время
	U64 nowTicks = rtc_get_time_in_ticks();
	
	//Обнуляем счетчик
	JournalRecordsCount=0;
			
	//Проверка
	if (findTicks==NULL_TIME)
			return 0;
	
	//Если время слишком маленькое, то сделаем его минимум 2001 годом
	if (findTicks<TICKS_2001)
			findTicks = TICKS_2001;
	
	//Если текущее время меньше, чем запрашиваемое, то ничего искать не надо
	if (findTicks>=nowTicks)
		return 0;
	
	//Увеличим тики на один, чтобы не отправлять предыдущую запись
	findTicks++;
	
	dt = ticks_to_time(findTicks);
	printf("Date and Time: %02d.%02d.%02d %02d:%02d:%02d\r\n",dt.Mday,dt.Mon,dt.Year,dt.Hour,dt.Min, dt.Sec);
	
	//Считываем записи
	while(JournalRecordsCount<MAX_COUNT_PER_PACKET)
	{
		//С большой долей вероятности, нужный файл искать не надо
		memset(path,0x00,sizeof(path));
		journal_form_path(path,findTicks);
		//Не повезло - нет такого файла
		if((f=fopen(path,"r"))==NULL)
		{
			//Ищем файл
			if (!journal_find_nearest2(&findTicks))
			{
				//printf("No file found %llu\r\n",findTicks);
				return 0;
			}
			else
				continue;
		}
		//Файл нашелся - ищем в самом файле
		else
		{
			//printf("Search in %s, ticks %llu\r\n",path,findTicks);
			while(JournalRecordsCount<MAX_COUNT_PER_PACKET)
			{
					//Считываем запись
					//Читать не получилось - EOF
					if (!fread(&record,sizeof(record),1,f))
					{
						//printf("End of File, move to another file\r\n");
						//Переходим на новый час!
						findTicks=((findTicks/TICKS_PER_HOUR)+1)*TICKS_PER_HOUR;
						break;
					}
					//То что надо
					if (record.ticks>=findTicks)
					{
						//printf("Read Data OK!");
						//Сохраняем запись 
						JournalRecords[JournalRecordsCount++] = record;
						//Новое значение тиков
						findTicks = record.ticks;
					}
			}
			
			//Закрываем файл
			fclose(f);	
		}
	}
	
	//Возвращаем количество записей
	return JournalRecordsCount;
}

/*
	Записываем в журнал
*/
U8 journal_write_record(P32T * data)
{
	char path[100];
	FILE *f;
	U8 count=0;
		
	//Куда писать?
	memset(path,0x00,sizeof(path));
	journal_form_path((char *)&path[0], data->ticks);
	
	//Открываем файл
	f = fopen(path,"a+");
	if (f==NULL)
	{
		printf("Could not open file %s\r\n",path);
	}
	else
	{
		//Пишем
		fwrite(data,sizeof(P32T),1,f);
		printf("Write to file %s OK\r\n",path);
		//Закрываем файл
		fclose(f);
	}
	return 1;
}

/*
	Формируем путь к файлу с данными на основании временной метки
*/
void journal_form_path(char * path, U64 ticks)
{
	
	char temp[10];
	//Файл для записи: год/месяц/день.dat
	DateTimeT dt = ticks_to_time(ticks);
	strcat(path,PATH_DATA_PREFIX); //Префикс
	memset(temp,0x00,sizeof(temp));sprintf(temp,"%d\\",dt.Year);strcat(path,temp);//Год
	memset(temp,0x00,sizeof(temp));sprintf(temp,"%d\\",dt.Mon);strcat(path,temp); //Месяц
	memset(temp,0x00,sizeof(temp));sprintf(temp,"%d\\",dt.Mday);strcat(path,temp); //День
	memset(temp,0x00,sizeof(temp));sprintf(temp,"%d",dt.Hour);strcat(path,temp); //Час
	strcat(path,FILE_DATA_EXT);//расширение
}

/*
	Ищем ближайший файл, где может храниться информация
*/
int journal_find_nearest(U64 *ticks)
{
	FINFO info;

	char path[100];
	U16 year;
	
	U8 count;
	U8 stop;
	U8 start;
	
	U8 findOK=0;
	
	DateTimeT requestTime = ticks_to_time(*ticks);
	DateTimeT currentTime = rtc_get_time();
	DateTimeT temp;
	
	printf("RequestTime: %02d.%02d.%02d %02d:%02d:%02d\r\n",requestTime.Mday,requestTime.Mon,requestTime.Year,requestTime.Hour,requestTime.Min, requestTime.Sec);
	printf("currentTime: %02d.%02d.%02d %02d:%02d:%02d\r\n",currentTime.Mday,currentTime.Mon,currentTime.Year,currentTime.Hour,currentTime.Min, currentTime.Sec);
	
	
	//Год как минимум текущий
	if (requestTime.Year<2013)
	{
		rtc_time_clear(&requestTime);
		requestTime.Year=2013;
	}
	
	//Ищем первый ближайший год
	findOK=0;
	for (year=requestTime.Year;year<=currentTime.Year;year++)
	{
		memset(path,0x00,sizeof(path));
		sprintf(path, "M0:\\DATA\\%04d\\*.*",year);
		printf("Search for %s\r\n",path);
		info.fileID=0;
		
		//Нашли папку с годом
		if (ffind(path,&info)==0)
		{
			findOK=1;
			printf("INFO: %s %d %d %d\r\n", info.name,info.size,info.fileID,info.attrib);
			printf("Search OK\r\n");
			//Год уже другой
			if (requestTime.Year != year)
			{
				rtc_time_clear(&requestTime);
				requestTime.Year = year;
			}
			break;
		}
	}
	
	//Не удалось ничего найти
	if (!findOK)
		return 0;
	
	
	//Ищем месяц
	if (requestTime.Year==currentTime.Year)
		stop = currentTime.Mon;
	else 
		stop=12;
	
	findOK=0;
	for (count = requestTime.Mon;count<=stop;count++)
	{
		memset(path,0x00,sizeof(path));
		sprintf(path, "M0:\\DATA\\%d\\%d\\*.*",requestTime.Year,count);
		printf("Search for %s\r\n",path);
		info.fileID=0;
		//Нашли папку с месяцем
		if (ffind(path,&info)==0)
		{
			findOK=1;
			printf("Search OK\r\n");
			//Месяц уже другой
			if (requestTime.Mon!=count)
			{
				temp = requestTime;
				rtc_time_clear(&requestTime);
				requestTime.Year = temp.Year;
				requestTime.Mon =count;
			}
			break;
		}
	}
	
	if (!findOK)
		return 0;
	
	//Ищем день
	if ((requestTime.Year==currentTime.Year)&&(requestTime.Mon==currentTime.Mon))
		stop = currentTime.Mday;
	else
		stop = 31;
	
	findOK=0;
	for (count=requestTime.Mday;count<=stop;count++)
	{
		memset(path,0x00,sizeof(path));
		sprintf(path, "M0:\\DATA\\%d\\%d\\%d\\*.*",requestTime.Year,requestTime.Mon,count);
		printf("Search for %s\r\n",path);
		info.fileID=0;	
		if (ffind(path,&info)==0)
			{
				findOK=1;
				printf("Search OK\r\n");
				//День уже другой
				if (requestTime.Mday!=count)
				{
					temp = requestTime;
					rtc_time_clear(&requestTime);
					
					requestTime.Year = temp.Year;
					requestTime.Mon  = temp.Mon;
					requestTime.Mday = count;
				}
				break;
			}
	}
	if (!findOK)
		return 0;
	
	//Ищем час
	if ((requestTime.Year==currentTime.Year)&&(requestTime.Mon==currentTime.Mon)&&(requestTime.Mday==currentTime.Mday))
		stop = currentTime.Hour;
	else 
		stop = 23;
	
	findOK=0;
	for (count=requestTime.Hour;count<=stop;count++)
	{
		memset(path,0x00,sizeof(path));
		sprintf(path, "M0:\\DATA\\%d\\%d\\%d\\%d.dat",requestTime.Year,requestTime.Mon,requestTime.Mday,count);
		printf("Search for %s\r\n",path);
		info.fileID=0;	
		if (ffind(path,&info)==0)
		{
			findOK=1;
			printf("Search OK\r\n");
			requestTime.Hour = count;
		}
	}
	
	if (!findOK)
		return 0;
	
	//Обновляем время
	*ticks = time_to_ticks(requestTime); 
	return  1;
	
}

/*
	Ищем первый ближайший файл
*/
int journal_find_nearest2(U64 *ticks)
{
	DateTimeT dt;
	DateTimeT temp;
	SearchStepT step = SearchYear;
	dt = ticks_to_time(*ticks);
	
	while(1)
	{
		if (!find_file(&dt,&step))
		{
			//printf("Step search not OK. Increment Data\r\n");
		}
		else 
		{
			printf("Search Success\r\n");
			*ticks = time_to_ticks(dt);
			return 1;
		}
		
		//Увеличиваем дату
		switch (step)
		{
			case SearchYear:
			{
				//Мы даже год не смогли найти - все, это конец
				return 0;
			}
			
			//Поиск месяца результатов не дал
			case SearchMonth:
			{
				
				//Надо увеличить год на один
				temp = dt;
				rtc_time_clear(&dt);
				dt.Year = temp.Year+1;
				//Продолжаем с поиска года
				step = SearchYear;
				break;
			}
			
			//Поиск дня результатов не дал
			case SearchDay:
			{
				//Надо увеличить месяц на один
				temp = dt;
				rtc_time_clear(&dt);
				dt.Year = temp.Year;
				dt.Mon=temp.Mon;
						
				if (dt.Mon==12)
				{
					dt.Mon=1;
					dt.Year++;
					//Продолжаем с поиска года
					step = SearchYear;
				}
				else 
				{
					dt.Mon++;
					step = SearchMonth;
				}
				
				break;
			}
			//Поиск часа не дал результата
			case SearchHour:
			{
				temp = dt;
				
				rtc_time_clear(&dt);
				
				dt.Year=temp.Year;
				dt.Mon = temp.Mon;
				dt.Mday=temp.Mday;
				
				//Увеличиваем день на один
				
				//Последний день месяца
				if (dt.Mday>=monthes[dt.Mon-1])
				{
					dt.Mday=1;
					//Последний месяц года
					if (dt.Mon==12)
					{
						dt.Mon=1;
						dt.Year++;
						step = SearchYear;
					}
					else
						step = SearchMonth;
				}
				else
				{
					dt.Mday++;
					step = SearchDay;
				}
				break;
			}
			
		}
		
		
	}
	
}

/*
	одна итерация по поиску файла
*/
int find_file(DateTimeT *dt, SearchStepT *step)
{
	FINFO info;
	char path[100];
	U8 findOK=0;
	
	U16 year;
	U8 start;
	U8 count;
	U8 stop;
	
	DateTimeT temp;
	//Текущая дата
	DateTimeT currentTime = rtc_get_time();
	
	//printf("Current Time: %02d.%02d.%02d %02d:%02d:%02d\r\n",currentTime.Mday,currentTime.Mon,currentTime.Year,currentTime.Hour,currentTime.Min, currentTime.Sec);
	//printf("Find Time: %02d.%02d.%02d %02d:%02d:%02d\r\n",dt->Mday,dt->Mon,dt->Year,dt->Hour,dt->Min, dt->Sec);

	
	while(1)
	{
		//Начиная с какого шага искать нужный файл
		switch (*step)
		{
			//------------------------------------------------------------
			//Ищем год
			case SearchYear:
			{
				findOK=0;
				for (year=dt->Year;year<=currentTime.Year;year++)
				{
					//Формируем путь для поиска
					memset(path,0x00,sizeof(path));
					sprintf(path, "M0:\\DATA\\%04d\\*.*",year);
					//printf("Search for %s\r\n",path);
					info.fileID=0;
					//Нашли папку с годом
					if (ffind(path,&info)==0)
					{
						//printf("Search OK\r\n");
						findOK=1;
						//Год уже другой - надо сбросить месяц, день и час для поиска 
						if (dt->Year != year)
						{
							rtc_time_clear(dt);
							dt->Year = year;
						}
						
						//Будем теперь искать месяц
						*step = SearchMonth;
						break;
					}
				}
				
				//Ничего мы не нашли
				if (!findOK)
					return 0;
				
				break;
			}
	
			//-----------------------------------------------------------
			//Ищем месяц
			case SearchMonth:
			{
				//Границы поиска
				if (dt->Year==currentTime.Year)
					stop = currentTime.Mon;
				else 
					stop=12;
	
				findOK=0;
				for(count=dt->Mon;count<=stop;count++)
				{
					memset(path,0x00,sizeof(path));
					sprintf(path, "M0:\\DATA\\%d\\%d\\*.*",dt->Year,count);
					//printf("Search for %s\r\n",path);
					info.fileID=0;
					//Нашли папку с месяцем
					if (ffind(path,&info)==0)
					{
						findOK=1;
						//printf("Search OK\r\n");
						//Месяц уже другой
						if (dt->Mon!=count)
						{
							temp = *dt;
							rtc_time_clear(dt);
							dt->Year = temp.Year;
							dt->Mon =count;
						}
						
						//Будeм теперь искать день
						*step = SearchDay;
						break;
					}
				}
				//Ничего не нашли
				if (!findOK)
					return 0;
				
				break;
			}
			
			//-----------------------------------------------------------
			//Ищем день
			case SearchDay:
			{
				if ((dt->Year==currentTime.Year)&&(dt->Mon==currentTime.Mon))
					stop = currentTime.Mday;
				else 
					stop = 31;
				findOK=0;
				
				for (count=dt->Mday;count<=stop;count++)
				{
					memset(path,0x00,sizeof(path));
					sprintf(path, "M0:\\DATA\\%d\\%d\\%d\\*.*",dt->Year,dt->Mon,count);
					//printf("Search for %s\r\n",path);
					info.fileID=0;	
					if (ffind(path,&info)==0)
					{
						findOK=1;
						//printf("Search OK\r\n");
						//День уже другой
						if (dt->Mday!=count)
						{
							temp = *dt;
							rtc_time_clear(dt);
	
							dt->Year = temp.Year;
							dt->Mon  = temp.Mon;
							dt->Mday = count;
						}
						//Будем теперь искать час
						*step= SearchHour;
						break;
					}
				}
				if (!findOK)
					return 0;
				break;
			}
			
			//-----------------------------------------------------------
			//Ищем час
			case SearchHour:
			{
				//Ищем час
				if ((dt->Year==currentTime.Year)&&(dt->Mon==currentTime.Mon)&&(dt->Mday==currentTime.Mday))
					stop = currentTime.Hour;
				else 		
					stop = 23;
	
				findOK=0;
				
					findOK=0;
					for (count=dt->Hour;count<=stop;count++)
					{
						memset(path,0x00,sizeof(path));
						sprintf(path, "M0:\\DATA\\%d\\%d\\%d\\%d.dat",dt->Year,dt->Mon,dt->Mday,count);
						//printf("Search for %s\r\n",path);
						info.fileID=0;	
						if (ffind(path,&info)==0)
						{
							//Наконец-то нашли!!!
							findOK=1;
							//printf("Search OK\r\n");
							dt->Hour = count;
							return 1;
						}
					}
	
					//опять пусто!
					if (!findOK)
						return 0;
	
				break;

			}
			
			case SearchEnd:
			{
				break;
			}
	};//end switch
	
	}
}
